package com.lemon.springcloud.core.listener.def;

import com.lemon.springcloud.core.component.zookeeper.ZkPropKeyListener;

import java.io.IOException;
import java.io.StringReader;
import java.util.*;

/**
 * Class Name: LemonZkPropertiesListener
 * Create Date: 6/20/18 11:17 AM
 * Creator: Chim·Zigui
 * Version: v1.0
 * Updater:
 * Date Time:
 * Description:
 */
public class LemonZkPropertiesListener {

    private List<ZkPropKeyListener> listeners = null;

    private Map<String, String> keyPathMapping = null;

    private Set<String> listeningPath = null;

    private Map<String, List<ZkPropKeyListener>> pathListener = null;

    public LemonZkPropertiesListener() {

    }

    public boolean addListener(String key, ZkPropKeyListener listener) {
        if (this.listeners == null) {
            this.listeners = new LinkedList<>();
        }
        this.listeners.add(listener);
        String path = keyPathMapping.get(key);
        putPathListener(path, listener);
        return true;
    }

    public void putPathListener(String path, ZkPropKeyListener listener) {
        if (this.pathListener == null) {
            this.pathListener = new HashMap<>();
        }
        List<ZkPropKeyListener> zkPropListeners = this.pathListener.computeIfAbsent(path, k -> new LinkedList<>());
        zkPropListeners.add(listener);
    }

    /**
     * 把配置key对应的zk path进行映射，用于查找对应的监听
     *
     * @param key
     * @param path
     * @return
     */
    public boolean putKeyPath(String key, String path) {
        if (this.keyPathMapping == null) {
            this.keyPathMapping = new HashMap<>();
        }
        boolean isExists = this.keyPathMapping.containsKey(key);
        this.keyPathMapping.put(key, path);
        return !isExists;
    }

    public void addListeningPath(String key) {
        String path = keyPathMapping.get(key);
        if (path != null) {
            if (this.listeningPath == null) {
                this.listeningPath = new HashSet<>();
            }
            this.listeningPath.add(path);
        }
    }

    public void onPropertyChange(String path, String changeData) {
        List<ZkPropKeyListener> zkPropListeners = this.pathListener.get(path);
        Properties properties = new Properties();
        try {
            properties.load(new StringReader(changeData));
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (zkPropListeners != null && zkPropListeners.size() > 0) {
            for (ZkPropKeyListener zkPropListener : zkPropListeners) {
                zkPropListener.onPropChanged(properties);
            }
        }
    }
}
